Stone Extension Library Release 1.0  Copyright ã1992 by Stone Design, Inc.  All Rights Reserved.

;RAPIReleaseNotes.rtf;;¬ Note: Please see the file RAPIReleaseNotes in this same directory for info on new API features for this release.

1	Reality Application Programmer's Interface

Application:	3DReality

Header File Directory:	«Somewhere»/Stone/Headers

Import:	<3dreality_api.h>

Introduction

The Reality Application Programmer's Interface (RAPI) is part of  the Stone Extensible Library (SEL). RAPI defines a set of Objective-C classes, protocols and categories, a set of useful debugging utilities, a full API, and a set of example source code that provides the basic building blocks to extend the capabilities of the 3DReality application.  More specifically, the RAPI is broken down into the following parts:

·	A set of classes and categories used to extend the capabilities of 3DReality.  This includes classes that are not meant to be subclassed by the developer, but instances of these classes will be made available at runtime for the developer to query and manipulate the 3D environment through (Camera).  Other classes (Shape, Quadric, ShapeInspector) are provided specifically so that the RAPI developer can subclass and augment their functionality.  As for categories, the N3DShapeExtensions category provides a set of methods that extend the basic capabilities of the N3DShape (and, therefore, the N3DLight) class. 

·	Within 3DReality, the RAPI provides a fully dynamic environment that addresses such issues as shared resources, debugging, and avoiding Objective-C name space collisions.  To install a resource into the environment, the developer simply places the resulting product of a bundle project into one of the standard (or non-standard, if the developer takes advantage of the 3DReality defaults that allow for changing the paths to the resource libraries) resource directories.  The next time 3DReality is executed, it will find the new resources and make them available-- in the case of resources like new geometries (Shapes), the new resource along with its icon will be displayed in the Shapes library.

·	For debugging purposes, a special debugging module is provided (accessible through either the defaults database or by renaming 3DReality.app to 3DReality.debug) through a menu in the 3DReality's main menu.  Fully documented source code and documentation is provided for a very basic debugging module.  With the addition of categories to this module (and menu items to the debugging menu), the debugging capabilies of the module can be easily extended.

·	Within a fully dynamic application environment, a common problem is Objective C name space collisions.  To address this issue, 3DReality provides for fully sharable resources between loadable modules.  To specify that a resource is to be sharable, the developer simply builds a string table (full documentation below) within the sharable bundle that lists all of the resources that the module needs to have present before it can successfully load.  When the module is requested to be loaded within 3DReality, the application queries the string table to find out what resources are needed and makes sure that those resources have been loaded before attempting to load the module.  In the future, full class versioning will be supported.

·	Also included with the RAPI environment are a number of example projects.  These include the debugging module (3DDebugUtilities), a simple geometry  (Sphere) that uses a shared resource (Quadric), a complex geometry (PatchMesh that uses several shared resources and provides interactive 3D editing, and a shared resource (Quadric).

By using these tools, the SEL developer can build extremely advanced and powerful 3D graphics easily.  Not only will these graphics reflect the capabilities that the SEL developer has devlopped, but they will also be able to take advantage of the myriad of features provided by 3DReality including textures, shaders, and the full manipulation of the shape hierarchy.

RAPI Classes, Categories, and Protocols

The RAPI provides a number of classes, categories, and protocols to aid in the development of extensions to 3DReality.  Those entities are listed below with a short description of the purpose of each.  Complete documentation can be found in the Classes directory.

Camera:  This is the class that provides the view port into the 3D world.  For the RAPI developer it provides an interface through which the shape hierarchy can be modified and sharable instances of shape resources can be archived/unarchived.

Shape:  The abstract superclass for all geometries within 3DReality.  The RAPI developer can subclass Shape (or any of the other abstract classes that are provided as extensions to Shape (Qudric, Polygon, BilinearPatch).  Through subclassing Shape and ShapeInspector, the RAPI developer can provide customized drag-and-drop compatible shapes with full, dynamic loaded, inspectors for use within the 3DReality environment.

ShapeInspector:  The abstract superclass for all shape inspectors.  By subclassing this and providing a custom user interface based on the template provided, any Shapes developped by the RAPI developer can have their own unique inspector that automatically appears within the inspector window whenever an instance of the shape is selected within a camera.

N3DShapeExtensions:  This category to shape provides a set of methods that the RAPI developer can take advantage of to make shader manipulation and hierarchy manipulation easier.

SliderCellFine/SliderDualActing:  Two powerful user interface classes that are commonly used within a shape's inspector UI to provide constrained value editing.  The basic functionality of these classes are easy to augment, but are powerful enough by themselves to oftentimes not need augmentation.  The Quadric example has a good example of how to take advantage of these classes.

Quadric/QuadricInspector:  An extension to Shape/ShapeInspector that provides standard editing for the parameters that quadrics (Sphere, Cylinder, Torus) have in common.  Also provided as an example of how to take advantage of sharable resources.

General Tutorial:

Using RAPI
    In order to write a loadable shape, you must create a subclass of Shape, which will be the object inserted in the worldHierarchy and that provides the RIB code for rendering that object.  In the simplest  loadable shape, this is the only class that you would need to define.  
    However, if you want to allow the user to manipulate certain attributes of your shape, then you need to define a subclass of Inspector.  This subclass would provide the conduit between your interface objects and your shape object.  Your interface objects should be placed in an inspector panel along the lines of PatchInspector.nib.  The way to do this is to use ShapeInspector.nib as the template panel for your shape's inspector panel.  This gives the field for the shape's name and the attribute switches for all the standard Shape attributes. 

Building a Loadable Bundle
Suppose you want to create a loadable shape called MyShape.  These are the steps
 you should take to create the bundle that will be loaded into 3DReality.

Create MyShape.bproj with Project Builder.

Create MyShape.tiff.  
	- This is the icon that is used to represent your shape.
    - Add file to project under images.
    
Create a file called "Bundle_requirements.strings".
    - This file should contain a line such as:
  		"BundleClass"		= "GeometryBundle";
    - This will ensure that MyShape.bundle is interpreted as a shape bundle. 
    - Add file to project under Other Resources.
    
Create MyShape.h and MyShape.m defining your class MyShape.  
    - Make sure to implement the methods init, doRenderSelf:, and calcBoundingBox.
    -  See Patch.m for more details.  
    - Add MyShape class to your PB.project.

Implementing an Inspector    
If you want to provide an inspector panel that allows the user to vary the values of certain 
attributes of your shape, then you should take the following steps:

Create MyShapeInspector.[hm] 
	- Wrap up the ids of the IB objects you want as outlets.
	- Provide methods as targets for the IB objects.  
	- Implement loadShape:inView: method for Inspector inits.
	- Send the information over to the selected shape, which should be MyShape.
	- See PatchInspector.[hm] for more details.
	
Create MyShapeInspector.nib in your project using ShapeInspector.nib as a template
    - You can open ShapeInspector.nib and then save it as MyShapeInspector.nib in
    the appropriate .lproj directory.  
	- Add the Stone3D API classes to IB.  You may need to add some AppKit classes
	as well.  Add MyShapeInspector.h to the nib.  
	- Make MyShapeInspector the File's Owner.
	- Make all the connections for your objects.  Also make sure that the standard
	Shape connections are made for changeName:, changeVisible:, and changeSolid:

Installing the Geometry bundles
	This is no trick.  You can just add the MyShape.bundle directly into 3DReality.app directory.
	
Shared Classes
	If you define several Geometry bundles and find that you need to share a class across these bundles, then you can create a bundle with that class and share it.  An example of this is the ControlPoint class used by both Patch and PatchMesh.  The steps to do this are:
	- Create a ControlPoint.bproj and add ControlPoint.[hm] files to the project and
	compile it as a bundle.  
	- Add ControlPoint.bundle to 3DReality.app/Library/Classes.  
	- Add  the following line to the Bundle_requirements.strings file of  Patch.bproj and
	PatchMesh.bproj:
		"RequiredClasses"	= "ControlPoint";
This is the mechanism for sharing classes.  The big key is the line in the requirements file.  This alerts the 3D Reality bundle manager to make sure the named classes are loaded in the runtime environment.

Misc Notes

Hierarchy Browser display of shape's name and number is created by the concatenation of a name joined with an underscore to a unique number:

1] If you want your shapes to be numbered from 1, add this code to your shape:

static int shapeNumber = 1;
- (int)shapeNumber
{
    return shapeNumber++;
}

Otherwise, the default number taken from Shape's implementation of shapeNumber will be used.

2] If you want a name other than the name of the class to appear in the Hierarchy Browser, simply override the "userName" method:

- (const char *)userName
{
    return "Elvis";
}